<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport"
        content="width=device-width, initial-scale=1.0, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        html {
            height: 100%;
        }

        body {
            height: 100%;
            background-image: url(https://img2.woyaogexing.com/2021/02/16/8501cd7ecb5b42eaa7ca5aded44b72f2!1080x1920.jpeg);
            background-size: cover;
            background-position: center center;
            padding: 10px;
        }

        [v-cloack] {
            display: none;
        }



        .ani1 {
            -webkit-animation: ani1 0.4s infinite alternate;
            animation: ani1 0.4s infinite alternate;
        }

        @keyframes ani1 {
            from {
                background-color: rgb(177, 237, 175)
            }

            to {
                background-color: rgb(90, 230, 85)
            }
        }

        h3 {
            text-shadow: 1px 1px 1px black;
            color: rgb(231, 212, 2);
            text-align: center;
        }

        .seatbox {
            display: flex;
            flex-wrap: wrap;
            justify-content: center;
        }

        .seat {
            float: left;
            text-align: center;
            font-size: 12px;
            width: 80px;
            margin: 5px;
            height: 32px;
            border: 1px solid #7bbcda;
            border-radius: 6px;
            position: relative;
        }

        .seat.kong {
            background-color: rgb(255, 255, 255);
        }

        .seat.zhan {
            background-color: #4ac50b;
            color: white
        }

        .seat p {
            margin: 0;

        }

        label {
            margin-right: 20px;
        }

        .toupiaobox {
            color: rgb(34, 32, 32);
            /* animation: ani2 0.3s infinite alternate; */
            /* border: 10px dotted red; */
            border: 1px solid #949393;
            overflow: hidden;
            position: relative;
            background-color: #ece03a;
        }

        .toupiaobox h1 {
            text-align: center;
        }

        @keyframes ani2 {
            from {
                background-color: rgb(238, 174, 147);
                border-color: #75a0e1;
            }

            to {
                background-color: rgb(238, 238, 135);
                border-color: #e7d402;
            }
        }

        .bar em {
            border-radius: 50%;
            display: inline-block;
            width: 9px;
            height: 9px;
            position: relative;
            top: 1px;
        }
    </style>
</head>

<body>
    <div id="app" v-cloack>
        <div class="bar" style="font-size: 10px; color: white;">
            <!-- 小圆形，连接状态指示 -->
            <em v-show="socketState == 0" style="background-color:rgb(236, 217, 12)"></em>
            <em v-show="socketState == 1" class="ani1" style="background-color:rgb(137, 236, 133)"></em>
            <em v-show="socketState == 2" style="background-color:rgb(207, 62, 9)"></em>

            <!-- 连接状态提示文字 -->
            <span v-show="socketState == 0">正在连接服务器</span>
            <span v-show="socketState == 1">通信正常</span>
            <span v-show="socketState == 2" style="background: #f40303; color:#e7d402">与服务器连接失败，请刷新重试</span>

            <span style="color:rgba(237, 241, 243, 0.376)">
                {{token}}
                {{gameNumber}}
                {{gameState}}
            </span>
        </div>

        <div style="background-color: #f7f7f7bd; border-radius: 5px; font-size: 13px;">
            <p v-show="woziji.seat">【座位号码】 {{woziji.seat}}</p>
            <p v-show="woziji.seat">【存活状态】 {{woziji.cunhuo}}</p>
        </div>

        <p v-show="woziji.shenfen">
            【你的身份】
            <button @click="tanchuangshenfen">
                点击显示
            </button>
        </p>
        <!-- <p>playerArr: {{playerArr}}</p> -->

        <div v-show="gameState == '等待开始'">
            <h3 style="color:#e7d402; text-align: center;">请选择你的座位</h3>
            <div class="seatbox" >
                <div v-for="i in 12" class="seat"
                    :class="{'zhan': playerArr.filter(item => item.seat == i).length != 0, 'kong': playerArr.filter(item => item.seat == i).length == 0}"
                    @click="seatDown(i)">
                    <p>{{i}}号座位</p>
                    <p v-show="woziji.seat != i">
                        {{playerArr.filter(item => item.seat == i).length ? '别人坐这里了' : '空'}}
                    </p>
                    <div v-show="woziji.seat == i">
                        <p style="color: rgb(255,236,66); font-weight: bold;">
                            我坐这里了
                            <span class="xicon" style="position: absolute; right: -10px; top: -8px;"
                                @click.stop="standup(i)">
                                <svg style="width: 20px;height: 20px;vertical-align: middle;fill: currentColor;overflow: hidden;"
                                    viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
                                    p-id="5953">
                                    <path
                                        d="M512 909.061224c-218.906122 0-397.061224-178.155102-397.061224-397.061224s178.155102-397.061224 397.061224-397.061224 397.061224 178.155102 397.061224 397.061224-178.155102 397.061224-397.061224 397.061224z"
                                        fill="#E5404F" p-id="5954"></path>
                                    <path
                                        d="M363.102041 680.75102c-5.22449 0-9.926531-2.089796-14.106123-5.746938-7.836735-7.836735-7.836735-20.37551 0-28.212245l297.795919-297.795919c7.836735-7.836735 20.37551-7.836735 28.212245 0 7.836735 7.836735 7.836735 20.37551 0 28.212245l-297.795919 297.795919c-4.179592 3.657143-8.881633 5.746939-14.106122 5.746938z"
                                        fill="#FFEEF0" p-id="5955"></path>
                                    <path
                                        d="M660.897959 680.75102c-5.22449 0-9.926531-2.089796-14.106122-5.746938l-297.795919-297.795919c-7.836735-7.836735-7.836735-20.37551 0-28.212245 7.836735-7.836735 20.37551-7.836735 28.212245 0l297.795919 297.795919c7.836735 7.836735 7.836735 20.37551 0 28.212245-4.179592 3.657143-8.881633 5.746939-14.106123 5.746938z"
                                        fill="#FFEEF0" p-id="5956"></path>
                                </svg>
                            </span>

                        </p>

                    </div>
                </div>
            </div>
        </div>


        <div class="toupiaobox" v-show="gameState == '发起投票' && this.woziji.seat  ">
            <span class="line"></span>
            <span class="line"></span>
            <span class="line"></span>
            <span class="line"></span>

            <h1 v-show="!checkYitou()">请投票 - {{toupiaomingcheng}}</h1>
            <h1 v-show="checkYitou()">你已经投完票了</h1>

            <div v-show="!checkYitou()" style="text-align: center;">
                <button style="width: 80px;height: 35px; margin: 5px;" v-for="i in 12" @click="toupiao(i)">
                    投{{i}}号
                </button>
                <button style="width: 80px;height: 35px; margin: 5px; " @click="toupiao(0)">
                    弃票
                </button>
            </div>
            <div v-show="checkYitou()" style="text-align: center; color: green;">
                请等待其他玩家投票结束
            </div>
        </div>

        <div>
            <h3 style="text-align: center; ">投票结果备忘录</h3>
            <div v-for="item in voteArr">
                <div v-show="!(gameState == '发起投票' && item.toupiaomingcheng == toupiaomingcheng && !checkYitou())">
                    <h4>【{{item.toupiaomingcheng}}】</h4>
                    <div v-for="(v, k) in zhenglivoteArr(item.v)" style="margin-right: 20px; overflow: hidden;">
                        <div style="float: left; width: 50%; display: flex; justify-content: space-around;">
                            <em style="font-style: normal; width: 80px;">
                                {{ k == '弃票' ? '弃票者' : k + '号获' + v.length + '票'}}
                            </em>
                            <svg class="icon"
                                style="width: 30px;height: 20px;vertical-align: middle;fill: currentColor;overflow: hidden;"
                                viewBox="0 0 2234 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6585">
                                <path d="M656.384 0v1024L0.093091 512z" fill="#1A6CFE" p-id="6586"></path>
                                <path d="M1102.382545 219.368727h-381.672727v590.848h381.672727z" fill="#1A6CFE"
                                    opacity=".8" p-id="6587"></path>
                                <path d="M1487.080727 219.368727h-258.048v590.848h258.048z" fill="#1A6CFE" opacity=".6"
                                    p-id="6588"></path>
                                <path d="M1861.818182 219.368727h-190.836364v590.848H1861.818182z" fill="#1A6CFE"
                                    opacity=".4" p-id="6589"></path>
                                <path d="M2234.181818 219.368727h-190.836363v590.848H2234.181818z" fill="#1A6CFE"
                                    opacity=".2" p-id="6590"></path>
                            </svg>
                        </div>
                        <div style="float: left;width: 50%; ">
                            {{v.map(item=>item+'号').join('、')}}
                        </div>
                    </div>
                </div>
            </div>
        </div>

    </div>
    <script src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        var socket

        var app = new Vue({
            el: '#app',
            data: {
                token: '',
                socketState: 0,
                gameNumber: 0,
                gameState: 'null',
                playerArr: [],  // 这个playerArr是经过服务器Game类脱敏之后的
                toupiaomingcheng: '',
                voteArr: [],

                character: '',
                alive: true
            },
            created() {
                // 检查本地存储
                let token = localStorage.getItem('langrenshatoken')
                if (token == null || token.length != 8) {
                    // 新玩家
                    token = this.generateRandomString(8)
                    localStorage.setItem('langrenshatoken', token)
                }

                this.token = token

                // 连接socket
                socket = io({
                    auth: {
                        token: token,
                        type: '玩家'
                    }
                });

                // 链接成功
                socket.on("connect", () => {
                    this.socketState = 1
                });

                // 链接失败
                socket.on("connect_error", () => {
                    this.socketState = 2
                });
                socket.on("disconnect", () => {
                    this.socketState = 2
                });

                // 消息
                socket.on("玩家连接时信息对齐", (o) => {
                    console.log('[玩家连接时信息对齐]' + JSON.stringify(o))
                    this.gameNumber = o.gameNumber
                    this.playerArr = o.playerArr
                    this.gameState = o.gameState
                    this.voteArr = o.voteArr
                    this.seat = o.seat
                    this.character = o.character
                    this.alive = o.alive
                });
                socket.on("座位信息广播", (o) => {
                    console.log('[座位信息广播]', JSON.stringify(o));
                    // 替换玩家信息中的playerArr
                    this.playerArr = o;
                });

                socket.on("发起投票", (toupiaomingcheng) => {
                    console.log(toupiaomingcheng);

                    this.gameState = '发起投票'
                    this.toupiaomingcheng = toupiaomingcheng
                });
            },
            computed: {
                // 在playerArr中得到自己
                woziji() {
                    if (this.playerArr.filter(item => item.token == this.token).length) {
                        return this.playerArr.filter(item => item.token == this.token)[0]
                    } else {
                        return {}
                    }
                }
            },
            methods: {
                // 整理投票arr
                // 收到的是[[3, 4],[5, 2], [4, 1], [10, 4], [11, 2]]
                // 要变成
                /*
                    {
                        4: [3, 10],
                        2: [5, 11]
                        1: [4],
                    }
                */
                zhenglivoteArr(arr) {
                    let o = {}
                    for (let i = 0; i < arr.length; i++) {
                        let from = arr[i][0]
                        let to = arr[i][1] == 0 ? '弃票' : arr[i][1]

                        if (to in o) {
                            o[to].push(from)
                            o[to].sort((a, b) => a - b)
                        } else {
                            o[to] = [from]
                        }
                    }
                    return o
                },
                checkYitou() {
                    for (let i = 0; i < this.voteArr.length; i++) {
                        if (this.voteArr[i].toupiaomingcheng == this.toupiaomingcheng) {

                            for (let j = 0; j < this.voteArr[i].v.length; j++) {
                                if (this.voteArr[i].v[j][0] == this.woziji.seat) {
                                    return true
                                }
                            }
                        }
                    }
                    return false
                },
                toupiao(i) {
                    let tip = ''
                    if (i == 0) {
                        tip = '确认要放弃投票么？？'
                    } else {
                        tip = '确认投' + i + '号么？'
                    }

                    if (confirm(tip)) {
                        socket.emit('玩家投票了', this.woziji.seat, i);
                    }

                },
                tanchuangshenfen() {
                    alert('你的身份是：\n 【' + this.woziji.shenfen + '】 \n 注意保密~~')
                },

                generateRandomString(length) {
                    let result = '';
                    const characters = 'ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghijklmnpqrstuvwxyz123456789';
                    const charactersLength = characters.length;
                    for (let i = 0; i < length; i++) {
                        result += characters.charAt(Math.floor(Math.random() * charactersLength));
                    }
                    return result;
                },
                // 坐下
                seatDown(n) {
                    if (this.playerArr.filter(item => item.seat == n).length) {
                        alert('已经有人占了' + n + '号座位')
                    } else {
                        socket.emit('玩家坐下', n);
                    }
                },
                // 起身
                standup(n) {
                    if (confirm('真的不玩了么？')) {
                        socket.emit('玩家起身');
                    }

                }
            }
        });
    </script>
</body>

</html>